package org.dromara.common.core.factory;

import org.dromara.common.core.utils.StringUtils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

import java.io.IOException;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：yml 配置源工厂
 */
/**
 * YmlPropertySourceFactory 类继承自 DefaultPropertySourceFactory，用于创建 PropertySource 工厂。
 * 它专注于从 YAML 文件中加载属性，提供了一种从 YAML 文件加载配置的灵活方式。
 * 通过扩展 DefaultPropertySourceFactory，该类能够利用 Spring Framework 提供的默认属性源工厂的功能，
 * 并在此基础上增加或覆盖特定的加载机制以支持 YAML 格式。
 */
public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {

    /**
     * 创建属性源。此方法判断资源文件是否为yaml格式，如果是，则使用YamlPropertiesFactoryBean进行处理，
     * 否则调用父类方法进行处理。
     *
     * @param name 属性源的名称
     * @param resource 要加载的资源
     * @return 返回创建的PropertySource对象
     * @throws IOException 如果读取资源发生错误
     */
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        // 获取资源的文件名，用于判断文件类型
        String sourceName = resource.getResource().getFilename();
        if (StringUtils.isNotBlank(sourceName) && StringUtils.endsWithAny(sourceName, ".yml", ".yaml")) {
            // 创建Yaml处理工厂
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            // 设置需要处理的资源
            factory.setResources(resource.getResource());
            // 初始化工厂
            factory.afterPropertiesSet();
            // 创建属性源对象并返回
            return new PropertiesPropertySource(sourceName, factory.getObject());
        }
        // 如果文件不是yaml格式，调用父类方法进行处理
        return super.createPropertySource(name, resource);
    }

}
